#include <iostream>
using namespace std;

// class A
//{
//
// };
//
// class B
//{
// private:
//	A _a;
// };
//
//
// int main()
//{
//
//	return 0;
// }

//  多态：
// 条件1： 虚函数的重写->父子类中的两个虚函数 函数名、参数、返回值相同。
// 条件2：父类指针或引用去调用虚函数
// class Person
//{
// public:
//	virtual  void BuyTicket(){
//		cout << "买票--全价" << endl;
//	}
//};
// class Student :public Person
//{
// public:
//	virtual void BuyTicket(){
//		cout << "买票——半价" << endl;
//	}
//};
// void Func(Person& p)//注意这里的引用。
//{
//	p.BuyTicket();
//}
// int main()
//{
//	Person p;
//	Student s;
//	Func(p);
//	Func(s);
//	return 0;
//}

// 协变：   （了解一下）
// class A {};
// class B : public A {}; // B 是 A 的派生类
// class Person {
// public:
//	virtual A* f() {
//		cout << "A::f()" << endl;
//		return new A;
//	}
// };
// class Student : public Person {
// public:
//	virtual B* f() {
//		cout << "B::f()" << endl;
//		return new B;
//	}
// };
//
// int main()
//{
//	Person* p = new Student;
//	p->f();
//	return 0;
// }

// 第二个例外

// class Person {
// public:
//	~Person(){
//		cout << "~Person()" << endl;
//	}
// };
// class Student : public Person {
// public:
//	~Student(){
//		cout << "~Student()" << endl;
//	}
// };
// int main()
//{
//	Person* p1 = new Person;
//	Person* p2 = new Student;// 创建一个Student对象，但以Person指针指向
//	delete p1;
//	delete p2;
//	return 0;
// }

// class Person {
// public:
//	virtual ~Person()
//	{
//		cout << "~Person()" << endl;
//	}
// };
// class Student : public Person {
// public:
//	virtual ~Student()
//	{
//		cout << "~Student()" << endl;
//	}
// };
// int main()
//{
//	Person* p1 = new Person;
//	Person* p2 = new Student;
//	delete p1;
//	delete p2;
//	return 0;
// }

// 普通调用vs多态调用

// T10

// final
// 实现一个类，这个类不能被继承。
// 1.父类构造函数私有化，派生实例化不出对象
// 2.C++11,final修饰的类为最终类，不能被继承
// class A final
//{
// public:
// protected:
//	int _a;
// private:
//	A()
//	{
//
//	}
// };
// class B :public A
//{
//
// };
// int main()
//{
//	B bb;
//	return 0;
// }

// override

// 多态的原理
// 继承和多态的两节课最后几十分钟都是讲原理
// class A
//{
// public:
//	virtual void func(int val = 1)
//	{
//		cout << "A->" << val << endl;
//	}
//	virtual void test() {
//		func();
//	}
// };
//
// class B :public A
//{
// public:
//	void func(int val = 0)
//	{
//		cout << "B->" << val << endl;
//	}
// };
//
// int main()
//{
//	B* p = new B;
//	p->test();
//
//	//p->func();
//	//B bb;
//	//bb.func();
//
//	return 0;
// }

// 多态调用：运行时去虚函数表中找函数的地址，进行调用，所以指向父类调用的是父类虚函数，
//		   指向子类调用的是子类虚函数。

// 原理讲解：
// class Base
//{
// public:
//	virtual void Func1()
//	{
//		cout << "Base::Func1()" << endl;
//	}
//	virtual void Func2()
//	{
//		cout << "Base::Func2()" << endl;
//	}
//	 void Func3()
//	{
//		cout << "Base::Func3()" << endl;
//	}
//	// void Func4()
//	//{
//	//	cout << "Func4()" << endl;
//	//}
// private:
//	int _b = 1;
//	char _ch = 'a';
// };
//
// class Derive :public Base
//{
// public:
//	virtual void Func1()
//	{
//		cout << "Derive::Func1()" << endl;
//	}
// private:
//	int _d = 2;
// };
// void f(Base* ptr)
//{
//	ptr->Func1();
// }

// int main()
//{
//	Base bb;
//	cout << sizeof(Base) << endl;
//
//	Derive dd;
//	f(&bb);
//	f(&dd);
//
//	return 0;
// }

// 多态原理——看着博客 自己调试

// class Person {
// public:
//	virtual void BuyTicket() { cout << "买票-全价" << endl; }
//	virtual void fun() {}
// private:
//	int a;
// };
// class Student : public Person {
// public:
//	virtual void BuyTicket() { cout << "买票-半价" << endl; }
// private:
//	int b;
// };
// void Func(Person* p)
//{
//	p->BuyTicket();
// }
// int main()
//{
//	Person p;
//	Student s;
//	Func(&p);
//	Func(&s);
//	return 0;
// }

// 抽象类
// 在虚函数的后面写上 = 0 ，则这个函数为纯虚函数。包含纯虚函数的类叫做抽象类（也叫接口
// 类），抽象类不能实例化出对象。派生类继承后也不能实例化出对象，只有重写纯虚函数，派生
// 类才能实例化出对象。纯虚函数规范了派生类必须重写，另外纯虚函数更体现出了接口继承
// class Car
//{
// public:
//	virtual void Drive() = 0;
// };
// class Benz :public Car
//{
// public:
//	virtual void Drive()
//	{
//		cout << "Benz-舒适" << endl;
//	}
// };
// class BMW :public Car
//{
////public:
////	virtual void Drive()
////	{
////		cout << "BMW-操控" << endl;
////	}
//};
// int main()
//{
//	Car mycar; // 错误：不能实例化抽象类
//
//	Car* pBenz = new Benz;  // 实例化 Benz 对象
//	pBenz->Drive();         // 调用 Benz 的 Drive 函数，输出 "Benz-舒适"
//
//	Car* pBMW = new BMW;// 错误：Benz 仍然是抽象类
//	pBMW->Drive();
//	return 0;
//}

// 这里常考一道笔试题：sizeof(Base)是多少？
// class Base
//{
// public:
//	virtual void Func1()
//	{
//		cout << "Func1()" << endl;
//	}
// private:
//	int _b = 1;
//};
// int main()
//{
//	Base b;
//	cout << sizeof(Base) << endl;
//	return 0;
//}

// class Base
//{
// public:
//	virtual void Func1()
//	{
//		cout << "Base::Func1()" << endl;
//	}
//	virtual void Func2()
//	{
//		cout << "Base::Func2()" << endl;
//	}
//	void Func3()
//	{
//		cout << "Base::Func3()" << endl;
//	}
// private:
//	int _b = 1;
// };
// class Derive : public Base
//{
// public:
//	virtual void Func1()
//	{
//		cout << "Derive::Func1()" << endl;
//	}
// private:
//	int _d = 2;
// };
// int main()
//{
//	Base b;
//	Derive d;
//	return 0;
// }